package com.neusoft.neuiotms.sap;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSONObject;
import com.neusoft.bizcore.web.dto.result.ResultDTO;
import com.neusoft.bizcore.web.dto.result.ResultListDTO;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.neuiotms.micro.cmdb.CmdbMicroService;

@Service
public class CmdbMicroServiceImpl implements CmdbMicroService {

    @Autowired
    private RestTemplate restTemplate;

    @Value("${cmdb.proxy.target-url}")
    private String cmdbServiceUrl;

    private final ParameterizedTypeReference<ResultDTO<JSONObject>> typeRef =
            new ParameterizedTypeReference<ResultDTO<JSONObject>>() {
            };

    @Override
    public ResultDTO<JSONObject> updateAttr(final String id, final String attr, final String dto) {

        final Map<String, Object> body = JsonUtils.jsonToMap(dto);

        final HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body);
        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/instances/%s/%s", id, attr), HttpMethod.PUT, entity,
                        this.typeRef);

        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> update(final String id, final String dto) {

        final Map<String, Object> body = JsonUtils.jsonToMap(dto);
        final HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body);
        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/instances/%s", id), HttpMethod.PUT, entity,
                        this.typeRef);

        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> deleteRelation(final String id, final String rid) {
        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/instances/%s/relations/%s", id, rid), HttpMethod.DELETE,
                        null,
                        this.typeRef);
        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> getRelation(final String id) {
        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/instances/%s/relations", id), HttpMethod.GET,
                        null,
                        this.typeRef);
        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> addRelation(final String id, final String dto) {
        final Map<String, Object> body = JsonUtils.jsonToMap(dto);
        final HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body);

        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/instances/%s/relations/add", id), HttpMethod.PUT,
                        entity,
                        this.typeRef);

        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> updateRelation(final String id, final String dto) {
        final Map<String, Object> body = JsonUtils.jsonToMap(dto);
        final HttpEntity<Map<String, Object>> entity = new HttpEntity<>(body);

        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/relationinstances/%s", id), HttpMethod.PUT,
                        entity,
                        this.typeRef);

        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultListDTO<JSONObject> getInstanceSchemaBySchemadef(final String schemadef) {
        final ParameterizedTypeReference<ResultListDTO<JSONObject>> listTypeRef =
                new ParameterizedTypeReference<ResultListDTO<JSONObject>>() {
                };

        final ResponseEntity<ResultListDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("/instances/schema/%s", schemadef), HttpMethod.GET,
                        null,
                        listTypeRef);

        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> getLocationTree() {
        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + "/instances/schema/SM_LOCATION/tree/by/parent", HttpMethod.GET,
                        null,
                        this.typeRef);
        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

    @Override
    public ResultDTO<JSONObject> getInstanceById(final String id) {
        final ResponseEntity<ResultDTO<JSONObject>> response = this.restTemplate
                .exchange(this.cmdbServiceUrl + String.format("instances/%s", id), HttpMethod.GET,
                        null,
                        this.typeRef);
        if (null != response) {
            return response.getBody();
        } else {
            throw new UnitedException("调用CMDB无响应");
        }
    }

}
